package com.stone.starter.core.script.tool;

import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * java 源码解析器
 * 参考：https://www.liaoxuefeng.com/article/1080190250181920
 *
 * @author Mr_wenpan@163.com 2021/9/7 8:03 下午
 */
public class ClassResolver {

    /**
     * 解析源码
     *
     * @param sourceCoe 源码
     * @return 解析结果
     */
    public static Result resolver(String sourceCoe) {
        String packageName = resolverPackage(sourceCoe);
        String className = resolverClass(sourceCoe);
        return Result.of(packageName, className);
    }

    /**
     * 解析源码中的包名
     */
    private static String resolverPackage(String sourceCoe) {
        Pattern pattern = Pattern.compile(PACKAGE_PATTERN);
        Matcher matcher = pattern.matcher(sourceCoe);
        if (!matcher.find()) {
            throw new RuntimeException("source code package not found!");
        }
        String matchPackage = matcher.group(0);
        matchPackage = StringUtils.remove(matchPackage, PACKAGE).trim();
        return StringUtils.remove(matchPackage, ";").trim();
    }

    /**
     * 解析源码中的类名
     */
    private static String resolverClass(String sourceCoe) {

        Pattern pattern = Pattern.compile(CLASS_NAME_PATTERN);
        Matcher matcher = pattern.matcher(sourceCoe);
        if (!matcher.find()) {
            throw new RuntimeException("source code class not found!");
        }
        String matchClass = matcher.group(0);
        return StringUtils.remove(matchClass, CLZ).trim();
    }

    /**
     * 类
     */
    private static final String CLZ = "class";

    /**
     * 包
     */
    private static final String PACKAGE = "package";

    /**
     * java 包匹配
     */
    private static final String PACKAGE_PATTERN = "package\\s*\\S*";

    /**
     * 类名称匹配
     */
    private static final String CLASS_NAME_PATTERN = "class[\\s*]\\S*";


    @Data
    public static class Result {
        private String packageName;
        private String className;
        private String classFullName;
        private String classFileName;

        public static Result of(String packageName, String className) {
            Result result = new Result();
            result.packageName = packageName;
            result.className = className;
            result.classFullName = result.packageName + "." + result.className;
            result.classFileName = result.className + ".java";
            return result;
        }
    }

}
